package ml2;

import java.util.Random;



/**
 * These workers take care of calculating the magnification map corresponding
 * a region of the shooting plane.
 * @author pgomez
 *
 */
public class RandomDeflector extends AbstractDeflector{

	private long _numberOfRays;
	private long _currentRay;


	public RandomDeflector(double[][] magnificationMap, double[][] shootingMap, StarBag starBag, 
			double startX, int nx,
			double startY, int ny,
			double sizeX, double sizeY,
			double pixelSize){
		super(magnificationMap, shootingMap, starBag,startX, nx,startY,  ny,sizeX,  sizeY,pixelSize);
	}

	@Override
	public void run() {
		double[] deflected;
		_initialTime = System.currentTimeMillis();
		double endX = _startX + _nx*_pixSize;
		double endY = _startY + _ny*_pixSize;

		double x =0;
		double y =0;
		int pixX=0;
		int pixY=0;
		int pixXs=0;
		int pixYs=0;

		_numberOfRays = _nx*_ny*DeflectionContext.nRays*DeflectionContext.nRays;
		double dx = endX -_startX;
		double dy = endY -_startY;
		Random generator = new Random();
		for (_currentRay = 0; _currentRay < _numberOfRays; _currentRay++) {
			x = _startX + generator.nextDouble() * dx;
			y = _startY + generator.nextDouble() * dy;
			deflected = getDeflected(x, y);
			deflected[0]+=DeflectionContext.sizeMap/2;
			deflected[1]+=DeflectionContext.sizeMap/2;
			if (deflected[0]>0 && deflected[0]<DeflectionContext.sizeMap && 
					deflected[1]>0 && deflected[1]<DeflectionContext.sizeMap){// The ray is in.
				pixX = (int)Math.floor(deflected[0]/_pixSize);
				pixY = (int)Math.floor(deflected[1]/_pixSize);
				pixXs= (int)Math.floor((x + _sizeX/2)/_pixSize);
				pixYs= (int)Math.floor((y + _sizeY/2)/_pixSize);
				_magnificationMap[pixY][pixX]++;
				_shootingMap[pixYs][pixXs]++;
			} else {
				_lostFlux++;
			}
			_totalFlux++;
		}
		_finalTime = System.currentTimeMillis();
	}

	public double getProgress(){
		return ((double)_currentRay)/_numberOfRays;
	}
}
